import sys
import colorama
from gamebase import *
import pygame

# core.CODE = [core.MESS]
# core.REVERSE = False


class HitEffect:
    def __init__(self, key):
        self.key = key
        self.startTime = time.time()

        self.live = 0.5  # 可存活时间

    def update(self):
        alpha = int((1 - ((time.time() - self.startTime) / self.live)) * 255)
        if alpha < 0:
            self.live = 0  # 标志着图像死亡
            return 0
        hitImage.set_alpha(         # 没有线程冲突，直接设置原图alpha没关系
            alpha
        )
        if not core.REVERSE:
            screen.blit(hitImage, (self.key * 100, 600))
        else:
            screen.blit(hitImage, (self.key * 100, 0))


class ErrEffect:
    # 图像加速下落
    def __init__(self, key):
        self.key = key
        self.startTime = time.time()
        self.live = 0.5  # 可存活时间
        self.a = 800  # 下落加速度

    def update(self):
        t = (time.time() - self.startTime)
        deltaX = 0.5 * self.a * t * t
        alpha = int((1 - (deltaX / 100)) * 255)
        if alpha < 0:
            self.live = 0  # 标志着图像死亡
            return 0
        errImage.set_alpha(
            alpha
        )
        if not core.REVERSE:
            screen.blit(errImage, (self.key * 100, 600 + deltaX))
        else:
            screen.blit(errImage, (self.key * 100, 0 - deltaX))
# load("config76628.ed");runGame()

def runGame():
    global screen
    core.lastTarget = 0  # 点击目标会使该变量 自减1, 当该变量值小于 LIMIT 时，会调用getBeatmap生成新铺面
    core.beatmap = []  # 铺面
    core.combo = 0  # 连击
    core.accList = [1]
    core.effectList = []
    core.slideList = []
    core.score = 0  # 命中数
    keyboardMap = core.getKeyboardMap()
    if not core.checkBoot():
        print(f"{colorama.Fore.RED}[Exception]{colorama.Fore.RESET}parameter CODE should be specified")
        return "Failed to start the game."
    screen = pygame.display.set_mode((core.KEY.value["key"] * 100, 700))
    pygame.display.set_caption("eatNote - by xi_to_porridge")
    timeJudge = TimeJudge(GAMESTATE, screen, core.TIMER)
    while True:
        FPSCounter.update()
        clock.tick(120)

        screen.fill((255, 255, 255))

        for event in pygame.event.get():
            # print(event)
            if event.type == pygame.QUIT:
                pygame.display.quit()
                raise Exception(
                    "Game exited."
                )
            if event.type == pygame.KEYDOWN:
                if event.unicode:
                    if event.unicode.lower() in keyboardMap:
                        CPSCounter.click()
                        key = keyboardMap.index(event.unicode.lower())
                        if core.beatmap[0][key] and timeJudge.gameState != END:
                            # 当 timeJudge.valid == False时, timeJudge.gameState == PLAYING
                            if not timeJudge.startTime:  # setup
                                timeJudge.startTime = time.time()
                                core.combo = 0  # 连击
                                core.accList = [1]
                                core.effectList = []
                                core.slideList = []
                                core.score = 0  # 命中数
                                timeJudge.gameState.set(PLAYING)

                            core.beatmap[0][key] = 0
                            hitSound.play()
                            core.effectList.append(HitEffect(key))
                            core.accList.append(1)
                            core.accList = core.accList[-1000:]
                            core.combo += 1
                            core.score += 1
                        else:
                            if timeJudge.gameState == PLAYING:
                                errSound.play()
                                core.effectList.append(ErrEffect(key))
                                core.accList.append(0)
                                core.accList = core.accList[-1000:]
                                core.combo = 0
                                timeJudge.gameState.set(END)

                        if sum(core.beatmap[0]) == 0:
                            core.beatmap.pop(0)
                            core.lastTarget -= 1
                            core.slideList.append(Slide())
                    elif event.key == 32 and timeJudge.gameState == END:
                        timeJudge.gameState.set(PREPARE)

        if core.lastTarget < core.LIMIT:
            newMap = core.getBeatmap(core.CODE)
            core.beatmap += newMap
            core.lastTarget += len(newMap)
            # 若加载osu/malody铺，不可使用core.LENGTH

        for i in range(1, core.KEY.value["key"]):
            pygame.draw.line(screen, (184, 223, 230), (100 * i, 0), (100 * i, 700))
        for i in range(7):
            for j in range(len(core.beatmap[i])):
                if core.beatmap[i][j]:
                    if not core.REVERSE:
                        screen.blit(targetImage, (j * 100, 600 - 100 * i - sum([slide.lastPx for slide in core.slideList])))
                    else:
                        screen.blit(targetImage, (j * 100, 100 * i + sum([slide.lastPx for slide in core.slideList])))# print(700-100*i)
            pygame.draw.line(screen, (184, 223, 230), (0, i * 100), (core.KEY.value["key"] * 100, i * 100))

        diedEffectList = []  # 特效的绘制与清除
        for effect in core.effectList:
            if effect.live:
                effect.update()
            else:
                diedEffectList.append(effect)
        for effect in diedEffectList:
            core.effectList.remove(effect)

        diedSlideList = []  # 特效的绘制与清除
        for slide in core.slideList:
            if slide.lastPx > 0:
                slide.update()
            else:
                diedSlideList.append(slide)
        for slide in diedSlideList:
            core.slideList.remove(slide)

        fpsText = my_font.render("fps:%d" % FPSCounter.getFPS(), True, (0, 0, 0))
        screen.blit(fpsText, (5, 10))

        CPSText = my_font.render("CPS:%d" % CPSCounter.getCPS(), True, (0, 0, 0))
        screen.blit(CPSText, (105, 10))

        accText = my_font.render("acc:%0.2f%%" % (sum(core.accList) / len(core.accList) * 100), True, (0, 0, 0))
        screen.blit(accText, (205, 10))

        comboText = my_font.render("combo:%d" % core.combo, True, (0, 0, 0))
        screen.blit(comboText, (305, 10))

        timeJudge.update()
        pygame.display.update()
        # print(beatmap)


